#include "main_window.hpp"

#include <widgets/status_label.hpp>

#include <QtCore/QCoreApplication>
#include <QtGui/QAction>
#include <QtGui/QStatusBar>
#include <QtGui/QMenu>
#include <QtGui/QMenuBar>
#include <QtGui/QToolBar>
#include <QtGui/QFileDialog>

#include <core/application.hpp>

#include <model/repository.hpp>

#include <widgets/status_label.hpp>

#include "workspace.hpp"

namespace gui
{

    main_window::main_window() :
    widgets::main_window(),
    open_repository_a_(0),
    close_repository_a_(0),
    save_repository_a_(0),
    create_repository_a_(0)
    {
        workspace_ = new workspace(this);
        setCentralWidget(workspace_);
        
        connect(this, SIGNAL(open_repository_request(const string&)),
                QApplication::instance(), SLOT(on_open_repository_request(const string&)));
        connect(this, SIGNAL(create_repository_request(const string&)),
                QApplication::instance(), SLOT(on_create_repository_request(const string&)));

        setMinimumSize(800, 600);
        setup_status_bar();
        init_widget_icon_resources();
        setup_actions();
        setup_menu_bar();
        setup_tool_bar();

        ws_ = new workspace(this);
        setCentralWidget(ws_);
        
        on_repository_closed();
    }

    main_window::~main_window()
    {
    }

    QAction* main_window::create_repository_action()
    {
        if (!create_repository_a_)
        {
            create_repository_a_ = new QAction(load_icon(":/icons/create_repository"),
                                               tr("&Create Repository..."), this);
            create_repository_a_->setShortcut(QKeySequence("Ctrl+n"));
            connect(create_repository_a_, SIGNAL(triggered()),
                    this, SLOT(on_create_repository_request()));
        }
        return create_repository_a_;
    }

    QAction* main_window::open_repository_action()
    {
        if (!open_repository_a_)
        {
            open_repository_a_ = new QAction(load_icon(":/icons/connect_repository"),
                                             tr("&Open Repository..."), this);
            open_repository_a_->setShortcut(QKeySequence("Ctrl+o"));
            connect(open_repository_a_, SIGNAL(triggered()),
                    this, SLOT(on_open_repository_request()));
        }
        return open_repository_a_;
    }

    QAction* main_window::save_repository_action()
    {
        if (!save_repository_a_)
        {
            save_repository_a_ = new QAction(load_icon(":/icons/save_repository"),
                                             tr("&Save Repository"), this);
            save_repository_a_->setShortcut(QKeySequence("Ctrl+s"));
            connect(save_repository_a_, SIGNAL(triggered()),
                    QApplication::instance(), SLOT(on_save_repository_request()));
        }
        return save_repository_a_;
    }

    QAction* main_window::close_repository_action()
    {
        if (!close_repository_a_)
        {
            close_repository_a_ = new QAction(load_icon(":/icons/disconnect_repository"),
                                              tr("&Close Repository"), this);
            connect(close_repository_a_, SIGNAL(triggered()),
                    QApplication::instance(), SLOT(on_close_repository_request()));
        }
        return close_repository_a_;
    }

    QIcon main_window::load_icon(const string& resource_path)
    {
        return QIcon(resource_path.c_str());
    }

    void main_window::setup_status_bar()
    {
        info_w_ = new widgets::status_label(this);
        info_w_->setText(tr("Starting up..."));

        statusBar()->addPermanentWidget(info_w_);
    }

    void main_window::setup_actions()
    {
        (void) open_repository_action();
        (void) close_repository_action();
        (void) save_repository_action();
        (void) create_repository_action();
    }

    void main_window::setup_menu_bar()
    {
        repository_m_ = new QMenu(tr("&Repository"), menuBar());
        repository_m_->addAction(create_repository_action());
        repository_m_->addAction(open_repository_action());
        repository_m_->addAction(save_repository_action());
        repository_m_->addAction(close_repository_action());

        menuBar()->addMenu(repository_m_);
    }

    void main_window::setup_tool_bar()
    {
        repository_tb_ = addToolBar(tr("Repository"));
        repository_tb_->addAction(create_repository_action());
        repository_tb_->addAction(open_repository_action());
        repository_tb_->addAction(save_repository_action());
        repository_tb_->addAction(close_repository_action());
    }

    void main_window::on_application_status_change(const QString& msg)
    {
        info_w_->set_status(msg);
    }

    void main_window::on_open_repository_request()
    {
        QString n = QFileDialog::getOpenFileName(this, tr("Open Repository"),
                                                 QDir::currentPath(),
                                                 tr("Gaia Fieldbook Repositories (*.gfr)"));
        if (!n.isEmpty())
        {
            emit open_repository_request(n.toStdString());
        }
    }

    void main_window::on_create_repository_request()
    {
        QString n = QFileDialog::getSaveFileName(this, tr("Create Repository"),
                                                 QDir::currentPath(),
                                                 tr("Gaia Fieldbook Repositories (*.gfr)"));
        if (!n.isEmpty())
        {
            emit create_repository_request(n.toStdString());
        }
    }

    void main_window::on_repository_closed()
    {
        open_repository_action()->setEnabled(true);
        close_repository_action()->setEnabled(false);
        save_repository_action()->setEnabled(false);
        create_repository_action()->setEnabled(true);
        on_application_status_change(tr("No Repository."));
        
        ws_->setEnabled(false);
    }

    void main_window::on_repository_opened(model::repository_ptr p)
    {
        if (!p)
        {
            return;
        }

        open_repository_action()->setEnabled(false);
        close_repository_action()->setEnabled(true);
        save_repository_action()->setEnabled(true);
        create_repository_action()->setEnabled(false);
        on_application_status_change(tr("Repository: %1").arg(p->path().c_str()));
        
        ws_->setEnabled(true);
    }
}
